#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/hash_policy.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
#define ps putchar(' ')
#define pe putchar('\n')
#define int long long
#define eb emplace_back
#define pi pair<int, int>
#define mk make_pair
#define fi first
#define se second
#define Ad tr[p].ad
// #define Ad t[p].ad
#define ls p << 1
#define rs p << 1 | 1
// #define ls tr[p].son[0]
// #define rs tr[p].son[1]
// #define ls t[p].son[0]
// #define rs t[p].son[1]
#define len (r - l + 1)
#define mid ((l + r) >> 1)
using namespace std;
// using namespace __gnu_pbds;
inline int read()
{
    int f = 0, ans = 0;
    char c = getchar();
    while (!isdigit(c))
        f |= c == '-', c = getchar();
    while (isdigit(c))
        ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
    return f ? -ans : ans;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
const int N = 1e5 + 5, M = 5e0 + 5, inf = 1e16, mod = 998244353;
int n, m, q, f[N][M];
int c[N], a[N][M];
struct Tree
{
    struct tree
    {
        int mx, ad;
    } tr[N << 2];
    void rebuild(int l, int r, int p)
    {
        tr[p] = {-inf, 0};
        return l == r ? void() : (rebuild(l, mid, ls), rebuild(mid + 1, r, rs));
    }
    inline void down(int p)
    {
        if (Ad)
        {
            tr[ls].mx += Ad, tr[ls].ad += Ad;
            tr[rs].mx += Ad, tr[rs].ad += Ad;
            Ad = 0;
        }
    }
    void add(int l, int r, int s, int t, int p, int w)
    {
        if (l >= s && r <= t)
        {
            tr[p].mx += w, Ad += w;
            return;
        }
        down(p);
        if (mid >= s)
            add(l, mid, s, t, ls, w);
        if (mid < t)
            add(mid + 1, r, s, t, rs, w);
        tr[p].mx = max(tr[ls].mx, tr[rs].mx);
    }
    int ask(int l, int r, int s, int t, int p)
    {
        if (l >= s && r <= t)
            return tr[p].mx;
        int ans = -inf;
        if (mid >= s)
            ans = ask(l, mid, s, t, ls);
        if (mid < t)
            ans = max(ans, ask(mid + 1, r, s, t, rs));
        return ans;
    }
    inline void rebuild() { rebuild(1, n, 1); }
    inline void add(int s, int t, int w) { add(1, n, s, t, 1, w); }
    inline int ask(int s, int t) { return s > t ? -inf : ask(1, n, s, t, 1); }
} t[6];
inline int solve(int l, int r)
{
    for (int i = 1; i <= m; ++i)
        t[i].rebuild(), f[l][i] = -inf;
    t[c[l]].add(l, l, inf + (f[l][c[l]] = a[l][c[l]]));
    for (int i = l + 1; i <= r; ++i)
    {
        for (int j = 1; j <= m; ++j)
            t[j].add(l, i - 1, a[i][j]), f[i][j] = -inf;
        t[c[i]].add(i, i, inf + (f[i][c[i]] = max(f[i - 1][c[i - 1]] + a[i][c[i]], t[c[i]].ask(l, i - 1))));
    }
    return f[r][c[r]];
}
signed main()
{
    freopen("paint.in", "r", stdin);
    freopen("paint.out", "w", stdout);
    n = read(), m = read(), q = read();
    for (int i = 1; i <= n; ++i)
        c[i] = read();
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            a[i][j] = read();
    int ans = solve(1, n);
    write(ans), pe;
    while (q--)
        if (read() == 1)
        {
            int p = read() ^ ans, x = read() ^ ans;
            c[p] = x;
        }
        else
        {
            int l = read() ^ ans, r = read() ^ ans;
            write(ans = solve(l, r)), pe;
        }
    return 0;
}
